package com.kele.modbus.handler;

import com.kele.clinet.DeviceComponent;
import com.kele.clinet.DeviceConfig;
import com.kele.message.response.read.ReadCoilsResponseFrame;
import com.kele.store.DeviceConfigStorage;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.apache.commons.collections4.CollectionUtils;

import java.net.SocketAddress;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 读取离散输入响应帧处理器
 */
public class ReadCoilsResponseFrameHandler extends SimpleChannelInboundHandler<ReadCoilsResponseFrame> {

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, ReadCoilsResponseFrame readCoilsResponseFrame) throws Exception {
        SocketAddress socketAddress = channelHandlerContext.channel().localAddress();
        DeviceConfig deviceConfig = DeviceConfigStorage.get(socketAddress);
        if (Objects.isNull(deviceConfig)){
            return;
        }
        List<DeviceComponent> componentList = deviceConfig.getComponentList();

        // 拿到所有的执行器
        List<DeviceComponent> actuatorList = componentList.stream()
                .filter(c -> Objects.equals(c.getType(), DeviceComponent.Type.ACTUATOR))
                .filter(c -> Objects.equals(c.getAddress(), readCoilsResponseFrame.getAddressCode()))
                .filter(c -> Objects.equals(c.getFunction(), readCoilsResponseFrame.getFunctionCode()))
                .collect(Collectors.toList());

        // 拿到所有寄存器信息，按照index排序
        List<DeviceComponent.Item> itemList = actuatorList.stream()
                .map(DeviceComponent::getItemList)
                .flatMap(List::stream)
                .sorted(Comparator.comparingInt(DeviceComponent.Item::getIndex))
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(itemList)){
            readCoilsResponseFrame.release();
            return;
        }

        int minIndex = itemList.get(0).getIndex();

        ByteBuf content = readCoilsResponseFrame.getContent();
        byte[] bytes = new byte[content.readableBytes()];
        content.readBytes(bytes);

        for (DeviceComponent.Item item : itemList) {
            int currentIndex = item.getIndex();
            int byteIndex = (currentIndex - minIndex) / 8;
            int result = (bytes[byteIndex] >> (currentIndex - minIndex) % 8) & 1;

            System.out.println(currentIndex + item.getName() + "-->" + result);
        }

        readCoilsResponseFrame.release();
    }
}
